package cn.taobaoke.restful.service;

import cn.taobaoke.restful.domain.OrderEntity;
import cn.taobaoke.restful.util.ExcelWorkbookFactory;
import cn.taobaoke.restful.util.StringUtil;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * @author yangzuo
 * @since 2017-03-11
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class FileService {

    public static final String TOTAL = "total";
    public static final String UPDATE = "update";
    public static final String INSERT = "insert";

    /**
     * 处理订单文件
     * 返回处理的订单数目
     * @param inputStream
     * @param filename
     * @return
     * @throws IOException
     */
    public Map handleExcelFile(InputStream inputStream, String filename, final Long domainId, final String domain) throws IOException {
        Integer totalCnt = 0;
        Integer insertCnt = 0;
        Integer updateCnt = 0;
        try (Workbook workbook = ExcelWorkbookFactory.create(inputStream, filename)) {
            Sheet sheet = workbook.getSheetAt(0); // 至少存在一个sheet页, 采用默认第一页.
            int start = sheet.getFirstRowNum();
            int end = sheet.getLastRowNum();
            Map<String, Integer> mapping = handleHeader(sheet.getRow(start));
            for (int i = start+1; i <= end; i++) {
                OrderEntity orderEntity = handleOrder(sheet.getRow(i), mapping);
                Map<String, Object> result = orderService.storeOrder(orderEntity, domainId, domain);
                if (OrderService.INSERT.equals((String) result.get(OrderService.ACTION))) {
                    insertCnt++;
                } else {
                    updateCnt++;
                }
                totalCnt++;
            }
        }

        Map<String, Object> result = new HashMap<>();
        result.put(TOTAL, totalCnt);
        result.put(INSERT, insertCnt);
        result.put(UPDATE, updateCnt);

        return Collections.unmodifiableMap(result);
    }

    public List<OrderEntity> handleExcelFiles(InputStream inputStream, String filename) throws IOException {
        List<OrderEntity> list = new ArrayList<>();
        try (Workbook workbook = ExcelWorkbookFactory.create(inputStream, filename)) {
            Sheet sheet = workbook.getSheetAt(0); // 至少存在一个sheet页, 采用默认第一页.
            int start = sheet.getFirstRowNum();
            int end = sheet.getLastRowNum();
            Map<String, Integer> mapping = handleHeader(sheet.getRow(start));
            for (int i = start+1; i <= end; i++) {
                OrderEntity orderEntity = handleOrder(sheet.getRow(i), mapping);
                list.add(orderEntity);
            }
        }
        return list;
    }

    /**
     * 计算订单中表头字段与所在index的映射关系.
     * @param row
     * @return
     */
    private Map<String, Integer> handleHeader(Row row) {
        Map<String, Integer> mapping = new HashMap<>();
        int first = row.getFirstCellNum();
        int last = row.getLastCellNum();
        for (int i = first; i < last; i++) {
            mapping.put(row.getCell(i).toString(), i);
        }
        return Collections.unmodifiableMap(mapping);
    }

    /**
     * 处理订单中订单数据, 通过表头字段映射关系获取对应数据.
     * @param row
     * @param mapping
     * @return
     */
    private OrderEntity handleOrder(Row row, Map<String, Integer> mapping) {
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setCreateTime(StringUtil.stringToDate(row.getCell(mapping.get("创建时间")).toString()));
        orderEntity.setClickTime(StringUtil.stringToDate(row.getCell(mapping.get("点击时间")).toString()));
        orderEntity.setCommodityInfo(row.getCell(mapping.get("商品信息")).toString());
        orderEntity.setCommodityId(row.getCell(mapping.get("商品ID")).toString());
        orderEntity.setAliWangwang(row.getCell(mapping.get("掌柜旺旺")).toString());
        orderEntity.setShop(row.getCell(mapping.get("所属店铺")).toString());
        orderEntity.setCommodityNum(StringUtil.stringToInteger(row.getCell(mapping.get("商品数")).toString()));
        orderEntity.setCommodityPrice(StringUtil.stringToDouble(row.getCell(mapping.get("商品单价")).toString()));
        orderEntity.setOrderStatus(row.getCell(mapping.get("订单状态")).toString());
        orderEntity.setOrderType(row.getCell(mapping.get("订单类型")).toString());
        orderEntity.setIncomeRatio(StringUtil.ratioStringToDouble(row.getCell(mapping.get("收入比率")).toString()));
        orderEntity.setShareRatio(StringUtil.ratioStringToDouble(row.getCell(mapping.get("分成比率")).toString()));
        orderEntity.setPayment(StringUtil.stringToDouble(row.getCell(mapping.get("付款金额")).toString()));
        orderEntity.setEffectPrediction(StringUtil.stringToDouble(row.getCell(mapping.get("效果预估")).toString()));
        orderEntity.setSettlementAmount(StringUtil.stringToDouble(row.getCell(mapping.get("结算金额")).toString()));
        orderEntity.setEstimatedIncome(StringUtil.stringToDouble(row.getCell(mapping.get("预估收入")).toString()));
        orderEntity.setSettlementTime(row.getCell(mapping.get("结算时间")).toString());
        orderEntity.setCommissionRate(StringUtil.ratioStringToDouble(row.getCell(mapping.get("佣金比率")).toString()));
        orderEntity.setCommissionAmount(StringUtil.stringToDouble(row.getCell(mapping.get("佣金金额")).toString()));
        orderEntity.setSubsidyRatio(StringUtil.ratioStringToDouble(row.getCell(mapping.get("补贴比率")).toString()));
        orderEntity.setSubsidyAmount(StringUtil.stringToDouble(row.getCell(mapping.get("补贴金额")).toString()));
        orderEntity.setSubsidyType(row.getCell(mapping.get("补贴类型")).toString());
        orderEntity.setTransactionPlatform(row.getCell(mapping.get("成交平台")).toString());
        orderEntity.setThirdParty(row.getCell(mapping.get("第三方服务来源")).toString());
        orderEntity.setOrderNumber(row.getCell(mapping.get("订单编号")).toString());
        orderEntity.setCategoryName(row.getCell(mapping.get("类目名称")).toString());
        orderEntity.setMediaId(row.getCell(mapping.get("来源媒体ID")).toString());
        orderEntity.setMediaName(row.getCell(mapping.get("来源媒体名称")).toString());
        orderEntity.setAdPositionId(row.getCell(mapping.get("广告位ID")).toString());
        orderEntity.setPidName(row.getCell(mapping.get("广告位名称")).toString());
        return orderEntity;
    }

    private final @NonNull OrderService orderService;

//    private static final Map<String, String> columnMapping = new HashMap<String, String>() {
//        {
//            put("创建时间", "");
//            put("点击时间", "");
//            put("商品信息", "");
//            put("商品ID", "");
//            put("掌柜旺旺", "");
//            put("所属店铺", "");
//            put("商品数", "");
//            put("商品单价", "");
//            put("订单状态", "");
//            put("订单类型", "");
//            put("收入比率", "");
//            put("分成比率", "");
//            put("付款金额", "");
//            put("效果预估", "");
//            put("结算金额", "");
//            put("预估收入", "");
//            put("结算时间", "");
//            put("佣金比率", "");
//            put("佣金金额", "");
//            put("补贴比率", "");
//            put("补贴金额", "");
//            put("补贴类型", "");
//            put("成交平台", "");
//            put("第三方服务来源", "");
//            put("订单编号", "");
//            put("类目名称", "");
//            put("来源媒体ID", "");
//            put("来源媒体名称", "");
//            put("广告位ID", "");
//            put("广告位名称", "");
//        }
//    };

}
